va_arg関数、va_start関数、va_end関数を使って、可変引数リストから引数の値を取得することができます。va_start関数は引数リストの初期化を、va_end関数は引数リストのリセットを行います。そして、va_arg関数で引数の値を取得します。これらの関数は、マクロとして実装されているかもしれません。
#include <stdarg.h>
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
apは引数リストを格納する領域を指定します。
lastは固定引数の最後の引数を指定します。
typeは取得する引数の型名を指定します。
これらの関数は同じ関数内で、va_start関数、va_arg関数、va_end関数の順に呼び出さなければなりません。そして、va_arg関数を呼び出す毎に引数リストから引数の値が取り出されます。
次の例題プログラムのVarPrint関数は第1引数は固定ですが、第2引数以降が可変になります。第1引数の文字列で、第2引数以降の引数の数と型名を指定しています。ちなみに、’c’は文字、’d’はdouble型浮動小数点数、’i’はint型整数、’s’は文字列を表します。
プログラム 例
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> int main() { /* ユーザ定義関数の宣言 */ void VarPrint(char *Format, ...); printf('1回目\n'); VarPrint('cdis', 'A', 3.14, 3, 'Hello.'); printf('\n2回目\n'); VarPrint('siiddccc', 'World.', 1, 2, 1.234, 56.789, 'a', 'b', 'c'); return 0; } /* 可変引数リストの値の表示 */ void VarPrint(char *p_format, ...) { va_list ap; /* 可変引数リストの初期化 */ va_start(ap, p_format); while (*p_format) { switch (*p_format) { case 'c': printf('%c\n', (char)va_arg(ap, int)); break; case 'd': printf('%f\n', va_arg(ap, double)); break; case 'i': printf('%d\n', va_arg(ap, int)); break; case 's': printf('%s\n', va_arg(ap, char *)); break; default: printf('引数の型名が不当です\n'); } ++p_format; } /* 可変引数リストのリセット */ va_end(ap); return; }
例の実行結果
$ ./va_arg.exe 1回目 A 3.140000 3 Hello. 2回目 World. 1 2 1.234000 56.789000 a b c $